package cn.hg.jbsa.common.web;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import com.jfinal.plugin.activerecord.Model;

import cn.hg.jboot.core.vo.BaseVo;
import cn.hg.jbsa.common.web.LayuiTreeSelect.LayuiTreeSelectItem;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;

/**
 * Layui TreeSelect控件结果对象
 * <p>https://gitee.com/wujiawei0926/treeselect</p>
 * 
 * @author 胡高
 * @date 2021/12/20
 */
public class LayuiTreeSelect<T extends Model<?>> extends BaseVo implements Iterable<LayuiTreeSelectItem<T>> {

    /**
     * 树状选择项VO
     * 
     * @author 胡高
     * @date 2021/12/20
     */
    public static class LayuiTreeSelectItem<T extends Model<?>> extends BaseVo {

        /**
         * serialVersionUID
         */
        private static final long serialVersionUID = 3131301585276339948L;

        /**
         * ID字段名
         */
        private String idField;

        /**
         * 父ID字段名
         */
        private String parentIdField;

        /**
         * 名称字段
         */
        private String nameField;

        /**
         * 子项列表
         */
        private List<LayuiTreeSelectItem<T>> children = new ArrayList<>();

        /**
         * 项目Bean
         */
        private T bean;

        public LayuiTreeSelectItem(T bean, String idField, String parentIdField, String nameField) {
            this.idField = idField;
            this.parentIdField = parentIdField;
            this.nameField = nameField;

            this.bean = bean;
        }

        /**
         * @return the children
         */
        public List<LayuiTreeSelectItem<T>> getChildren() {
            return this.children;
        }

        /**
         * @return the id
         */
        public String getId() {
            return this.bean.getStr(this.idField);
        }

        /**
         * @return the name
         */
        public String getName() {
            return this.bean.getStr(this.nameField);
        }

        public boolean getOpen() {
            return !CollUtil.isEmpty(this.children);
        }

        /**
         * @return the parentId
         */
        public String getParentId() {
            return this.bean.getStr(this.parentIdField);
        }

        /**
         * @param children
         *            the children to set
         */
        protected void setChildren(List<LayuiTreeSelectItem<T>> children) {
            this.children = children;
        }

    }

    /**
     * serialVersionUID
     */
    private static final long serialVersionUID = 3562904133537565003L;

    /**
     * 树对象数组
     */
    private List<LayuiTreeSelectItem<T>> data;

    /**
     * 通过ID字段名、上级ID字段名、name字段名、初始顶层ID值创建树对象
     * 
     * @param beanList bean对象列表
     * @param idField ID字段名
     * @param parentIdField 上级字段名
     * @param nameField name字段名
     * @param parentIdValue 初始顶层ID值
     */
    public LayuiTreeSelect(List<T> beanList, String idField, String parentIdField, String nameField,
        Object parentIdValue) {

        // 转换项目列表为树状选择项列表
        List<LayuiTreeSelectItem<T>> itemList =
            this.convertToItemList(beanList, idField, parentIdField, nameField, parentIdValue);

        // 构建树状对象
        this.data = this.buildTree(itemList, parentIdValue);
    }

    public void add(int index, LayuiTreeSelectItem<T> element) {
        this.data.add(index, element);
    }

    private List<LayuiTreeSelectItem<T>> buildTree(final List<LayuiTreeSelectItem<T>> beanList, Object parentId) {
        List<LayuiTreeSelectItem<T>> data = new ArrayList<>();

        for (LayuiTreeSelectItem<T> item : beanList) {

            if (ObjectUtil.equals(parentId, item.getParentId())) {
                data.add(item);
            }

        }

        for (LayuiTreeSelectItem<T> org : data) {
            org.setChildren(this.buildTree(beanList, org.getId()));
        }

        return data;
    }

    private List<LayuiTreeSelectItem<T>> convertToItemList(List<T> list, String idName, String parentIdName,
        String nameField, Object initParentId) {
        List<LayuiTreeSelectItem<T>> itemList = new ArrayList<>();
        for (T bean : list) {
            itemList.add(new LayuiTreeSelectItem<>(bean, idName, parentIdName, nameField));
        }

        return itemList;
    }

    @Override
    public Iterator<LayuiTreeSelectItem<T>> iterator() {
        return this.data.iterator();
    }
}
